#!/usr/bin/env python

from socket import *
from time import time,ctime,sleep
import sys
import threading
import string
import getopt

def Useage():
    print """
+---------------------------------------------------+
+ Useage: python pyscan.py -p <port> -h <IP-range>
+---------------------------------------------------+
+ eg:
+    python pyscan.py -p 3389 -h 10.0.0.1-10.0.0.255
+
+---------------------------------------------------+
+ ps: for class C IP only :)
+---------------------------------------------------+
"""

class PyScan:
    def __init__(self,args = []):
        self.host_list = []
        self.open_list = []
        self.open_cnt = 0
        try:
            self.sk = socket(AF_INET, SOCK_STREAM)
        except:
            print "Socket Error!"
            sys.exit(1)
        self.sk.settimeout(0.1)
	#
        #Get options
        #
        opts, argvs = getopt.getopt(args[1:], "h:p:")
        for opt,argv in opts:
            if opt == "-p":
                self.port = int(argv)
            elif opt == "-h":
                self.ips = argv
                self.start_ip = self.ips.split("-")[0]
                try:
                    self.end_ip = self.ips.split("-")[1]
                except IndexError:
                    print "Starting scanning..."
                    self.scan(self.start_ip, self.port)
                    sys.exit(1)
                
        
        # Verify IP range
        if len(self.start_ip.split(".")) != 4:
            print "Invaild IP Address:"+self.start_ip
            Useage()
            sys.exit(1)
        else:
            s_net = string.join(self.start_ip.split(".")[:3],".")
            s = int(self.start_ip.split(".")[3])
            
        if len(self.end_ip.split(".")) !=4:
            print "Invaild IP Address:"+self.end_ip
            Useage()
            sys.exit(1)
        else:
            e_net = string.join(self.end_ip.split(".")[:3],".")
            e = int(self.end_ip.split(".")[3])
        if s_net != e_net:
            print "Invaild option."
            Useage()
            sys.exit(1)
        if s > e:
            print "End IP address is lager than start IP"
            Useage()
            sys.exit(1)
            
        # Build IP list   
        for i in range(s,e+1):
            ip = s_net +"."+ str(i)
            self.host_list.append(ip)
        #print self.host_list

    def scan(self,host, port):
        addr = (host, port)
        
        #sys.stdout.flush()
        #sys.stderr.flush()
        #print "Trying %s\r" %(host)
        
        try:
            self.sk.connect(addr)
        except:
            sys.stderr.write(host+'\tCLOSED\r')
            sleep(0.01)
        else:
            self.open_list.append(host)
            sys.stderr.write("%s\tOPEN\r" % (host))
            sleep(0.01)
        
    def run(self):
        print "-"*16
        print "Port Specified: %d" % (self.port)
        print "-"*16
        print "Start Scanning at %s" % (ctime(time()))
        for ip in self.host_list:
            self.scan(ip, self.port)
        print "%d IP(s) Scaned,%d host(s) opens port: %d" % \
        (len(self.host_list),len(self.open_list),self.port)
        for h in self.open_list:
            print h
        print "End Scanning at %s" % (ctime(time()))
	self.sk.close()
        
if __name__== "__main__":
    s = PyScan(sys.argv)
    s.run()